// Fill out your copyright notice in the Description page of Project Settings.


#include "PetBaseCharacter.h"

#include "NavigationSystem.h"
#include "PlayCharacter.h"
#include "AIModule/Classes/AIController.h"
#include "Blueprint/AIBlueprintHelperLibrary.h"
#include "Kismet/GameplayStatics.h"
#include "Kismet/KismetMathLibrary.h"
#include "Kismet/KismetSystemLibrary.h"

// Sets default values
APetBaseCharacter::APetBaseCharacter()
{
	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
}

// Called when the game starts or when spawned
void APetBaseCharacter::BeginPlay()
{
	Super::BeginPlay();
	RestMode();
	LatentInfo = FLatentActionInfo(0, FMath::Rand(),TEXT("RandomPlayNearbyMove"), this);
	RandomPlayNearbyMoveCheck();
	PlayAnimMontage(CallMontage);
}

// Called every frame
void APetBaseCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (GetVelocity().Length() > 0.f)
	{
		RestMode();
		RandomPlayNearbyMoveCheck();
		isRandom = true;
	}
	if (GetVelocity().Length() <= 0.f)
	{
		if(isRandom)
		{
			isRandom = false;
		}
	}
	MovePlayAssignLocation();

	MovePlayPosition();

	DeliverPlayNearby();
}

// Called to bind functionality to input
void APetBaseCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
}

void APetBaseCharacter::RestMode()
{
	IsReset = false;
	 FLatentActionInfo LatentInfo2(0, FMath::Rand(),TEXT("SetRestTrue"), this);
	UKismetSystemLibrary::RetriggerableDelay(this, 5.f, LatentInfo2);
}

void APetBaseCharacter::MovePlayAssignLocation()
{
	APlayCharacter* MyCharacter = Cast<APlayCharacter>(UGameplayStatics::GetPlayerPawn(this, 0));
	if (!MyCharacter->PetMoveLocation.Equals(FVector::Zero()))
	{
		Cast<AAIController>(GetController())->MoveToLocation(MyCharacter->PetMoveLocation);
		MyCharacter->PetMoveLocation = FVector::Zero();
	}
}

void APetBaseCharacter::CopyProp(APetBaseCharacter* source)
{
	this->Name = source->Name;
	this->Head = source->Head;
	this->LV = source->LV;
	this->Health = source->Health;
	this->CurrentHealth = source->CurrentHealth;
	this->CurrentHealth = source->CurrentHealth;
	this->AttackPower = source->AttackPower;
	this->Defense = source->Defense;
	this->QualificationAttr = source->QualificationAttr;
	this->Favorability = source->Favorability;
	this->Hunger = source->Hunger;
	this->CurrentHunger = source->CurrentHunger;
	this->GetMesh()->SetSkeletalMesh(source->GetMesh()->SkeletalMesh);
	this->GetMesh()->SetAnimInstanceClass(source->GetMesh()->AnimClass);
	this->GetMesh()->InitializeAnimScriptInstance(true);
}

void APetBaseCharacter::MovePlayPosition()
{
	APlayCharacter* MyCharacter = Cast<APlayCharacter>(UGameplayStatics::GetPlayerPawn(this, 0));
	FVector ActorLocationXY = FVector(GetActorLocation().X, GetActorLocation().Y, 0);
	FVector PlayLocationXY = FVector(MyCharacter->GetActorLocation().X, MyCharacter->GetActorLocation().Y, 0);
	// 超过1000跟随玩家
	if (UKismetMathLibrary::Vector_Distance(ActorLocationXY, PlayLocationXY) > 1000)
	{
		UE_LOG(LogTemp, Log, TEXT("开始向玩家移动"))
		FRotator NewRotator = UKismetMathLibrary::FindLookAtRotation(ActorLocationXY, PlayLocationXY);
		SetActorRotation(NewRotator);

		Cast<AAIController>(GetController())->MoveToLocation((GetActorLocation() + (GetActorForwardVector() * 700)));
	}
}

void APetBaseCharacter::DeliverPlayNearby()
{
	APlayCharacter* MyCharacter = Cast<APlayCharacter>(UGameplayStatics::GetPlayerPawn(this, 0));
	FVector ActorLocationXY = FVector(GetActorLocation().X, GetActorLocation().Y, 0);
	FVector PlayLocationXY = FVector(MyCharacter->GetActorLocation().X, MyCharacter->GetActorLocation().Y, 0);
	// 超过1000跟随玩家
	if (UKismetMathLibrary::Vector_Distance(ActorLocationXY, PlayLocationXY) > 2000)
	{
		UE_LOG(LogTemp, Log, TEXT("传送玩家附近"))
		UNavigationSystemV1* NavSystem = UNavigationSystemV1::GetNavigationSystem(GetController());
		FNavLocation ResultLocation;
		NavSystem->GetRandomPointInNavigableRadius(MyCharacter->GetActorLocation(), 500, ResultLocation);
		UE_LOG(LogTemp, Log, TEXT("传送玩家位置 有节点参考 %s"),ResultLocation.HasNodeRef()?TEXT("有"):TEXT("无"));
		if(ResultLocation.HasNodeRef())
		{
			UE_LOG(LogTemp, Log, TEXT("传送玩家位置 x %f,y %f,z %f"),ResultLocation.Location.X,ResultLocation.Location.Y,GetActorLocation().Z);
			FVector NewLocation(ResultLocation.Location.X,ResultLocation.Location.Y,GetActorLocation().Z);
			const float XGrp = NewLocation.X - MyCharacter->GetActorLocation().X;
			const float YGrp = NewLocation.Y - MyCharacter->GetActorLocation().Y;
			if(FMath::Abs(XGrp) < 100)
			{
				if( XGrp > 0) NewLocation.X += 100;
				if( XGrp <= 0) NewLocation.X -= 100;
			}
			if(FMath::Abs(YGrp) < 100)
			{
				if( YGrp > 0) NewLocation.Y += 100;
				if( YGrp <= 0) NewLocation.Y -= 100;
			}
			K2_TeleportTo(NewLocation,GetActorRotation());
			FRotator NewRotator = UKismetMathLibrary::FindLookAtRotation(ActorLocationXY, PlayLocationXY);
			SetActorRotation(NewRotator);	
		}
	}
}

void APetBaseCharacter::RandomPlayNearbyMoveCheck()
{
	UKismetSystemLibrary::RetriggerableDelay(this, 10.f, LatentInfo);
}

void APetBaseCharacter::RandomPlayNearbyMove()
{
	if(!isRandom)
	{
		isRandom= true;
		APlayCharacter* MyCharacter = Cast<APlayCharacter>(UGameplayStatics::GetPlayerPawn(this, 0));

		UNavigationSystemV1* NavSystem = UNavigationSystemV1::GetNavigationSystem(GetController());
		FNavLocation ResultLocation;
		NavSystem->GetRandomPointInNavigableRadius(MyCharacter->GetActorLocation(), 500, ResultLocation);
		if(ResultLocation.HasNodeRef())
		{
			UE_LOG(LogTemp, Log, TEXT("随机移动 x %f,y %f,z %f"),ResultLocation.Location.X,ResultLocation.Location.Y,GetActorLocation().Z);
			FVector NewLocation(ResultLocation.Location.X,ResultLocation.Location.Y,GetActorLocation().Z);
			const float XGrp = NewLocation.X - MyCharacter->GetActorLocation().X;
			const float YGrp = NewLocation.Y - MyCharacter->GetActorLocation().Y;
			if(FMath::Abs(XGrp) < 200)
			{
				if( XGrp > 0) NewLocation.X += 200;
				if( XGrp <= 0) NewLocation.X -= 200;
			}
			if(FMath::Abs(YGrp) < 200)
			{
				if( YGrp > 0) NewLocation.Y += 200;
				if( YGrp <= 0) NewLocation.Y -= 200;
			}
			isRandom= true;
			UAIBlueprintHelperLibrary::SimpleMoveToLocation(GetController(),NewLocation);
		}
	}

}
